/* LwIP SNTP example

   This example code is in the Public Domain (or CC0 licensed, at your option.)

   Unless required by applicable law or agreed to in writing, this
   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
   CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>
#include "esp_system.h"
#include "esp_event.h"
#include "esp_log.h"
#include "esp_attr.h"
#include "esp_sleep.h"
#include "esp_mac.h"
#include "esp_wifi.h"
#include "esp_http_client.h"
#include "esp_sntp.h"
#include "nvs_flash.h"
#include "protocol_examples_common.h"
#include "esp_netif_sntp.h"
#include "lwip/ip_addr.h"
#include "lwip/err.h"
#include "lwip/sys.h"
#include "soft_spi.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "cJSON.h"

#if CONFIG_BT_CONTROLLER_ENABLED || !CONFIG_BT_NIMBLE_ENABLED
#include "esp_bt.h"
#endif
#include "esp_blufi_api.h"
#include "blufi_example.h"
#include "esp_blufi.h"

#define EXAMPLE_WIFI_CONNECTION_MAXIMUM_RETRY 2
#define EXAMPLE_INVALID_REASON                255
#define EXAMPLE_INVALID_RSSI                  -128

#define XINZHI_API_KEY "SPayx4QrNEOZqi7Nk"
#define XINZHI_API_URL "http://api.seniverse.com/v3/weather/now.json?key=" XINZHI_API_KEY "&location=wuxi&language=en&unit=c"
#define MAX_HTTP_OUTPUT_BUFFER 512

static void example_event_callback(esp_blufi_cb_event_t event, esp_blufi_cb_param_t *param);

#define WIFI_LIST_NUM   10

static wifi_config_t sta_config;

/* FreeRTOS event group to signal when we are connected & ready to make a request */
static EventGroupHandle_t wifi_event_group;

/* The event group allows multiple bits for each event,
   but we only care about one event - are we connected
   to the AP with an IP? */
const int CONNECTED_BIT = BIT0;

static uint8_t example_wifi_retry = 0;

/* store the station info for send back to phone */
static bool gl_sta_connected = false;
static bool gl_sta_got_ip = false;
static bool ble_is_connected = false;
static uint8_t gl_sta_bssid[6];
static uint8_t gl_sta_ssid[32];
static int gl_sta_ssid_len;
static wifi_sta_list_t gl_sta_list;
static bool gl_sta_is_connecting = false;
static esp_blufi_extra_info_t gl_sta_conn_info;

static const char *TAG = "example";

/* Variable holding number of times ESP32 restarted since first boot.
 * It is placed into RTC memory using RTC_DATA_ATTR and
 * maintains its value when ESP32 wakes from deep sleep.
 */
RTC_DATA_ATTR static int boot_count = 0;
uint64_t global_time_show = 0x0000F0030000;

static void obtain_time(void);

static void example_record_wifi_conn_info(int rssi, uint8_t reason)
{
    memset(&gl_sta_conn_info, 0, sizeof(esp_blufi_extra_info_t));
    if (gl_sta_is_connecting) {
        gl_sta_conn_info.sta_max_conn_retry_set = true;
        gl_sta_conn_info.sta_max_conn_retry = EXAMPLE_WIFI_CONNECTION_MAXIMUM_RETRY;
    } else {
        gl_sta_conn_info.sta_conn_rssi_set = true;
        gl_sta_conn_info.sta_conn_rssi = rssi;
        gl_sta_conn_info.sta_conn_end_reason_set = true;
        gl_sta_conn_info.sta_conn_end_reason = reason;
    }
}

static void example_wifi_connect(void)
{
    example_wifi_retry = 0;
    gl_sta_is_connecting = (esp_wifi_connect() == ESP_OK);
    example_record_wifi_conn_info(EXAMPLE_INVALID_RSSI, EXAMPLE_INVALID_REASON);
}

static bool example_wifi_reconnect(void)
{
    bool ret;
    if (gl_sta_is_connecting && example_wifi_retry++ < EXAMPLE_WIFI_CONNECTION_MAXIMUM_RETRY) {
        printf("BLUFI WiFi starts reconnection\n");
        gl_sta_is_connecting = (esp_wifi_connect() == ESP_OK);
        example_record_wifi_conn_info(EXAMPLE_INVALID_RSSI, EXAMPLE_INVALID_REASON);
        ret = true;
    } else {
        ret = false;
    }
    return ret;
}

static int softap_get_current_connection_number(void)
{
    esp_err_t ret;
    ret = esp_wifi_ap_get_sta_list(&gl_sta_list);
    if (ret == ESP_OK)
    {
        return gl_sta_list.num;
    }

    return 0;
}

static void weather_task(void *pvParameters)
{
    char output_buffer[MAX_HTTP_OUTPUT_BUFFER] = {0};

    esp_http_client_config_t config = {
        .url = XINZHI_API_URL,
        .method = HTTP_METHOD_GET,
    };
    esp_http_client_handle_t client = esp_http_client_init(&config);

    while (1) {
        esp_err_t err = esp_http_client_open(client, 0);
        if (err == ESP_OK) {
            int content_length = esp_http_client_fetch_headers(client);
            if (content_length < 0) {
                ESP_LOGE("weather_task", "HTTP client fetch headers failed");
            } else {
                int data_read = esp_http_client_read_response(client, output_buffer, MAX_HTTP_OUTPUT_BUFFER - 1);
                if (data_read >= 0) {
                    output_buffer[data_read] = '\0';
                    // JSON解析
                    cJSON *root = cJSON_Parse(output_buffer);
                    if (root) {
                        cJSON *results = cJSON_GetObjectItem(root, "results");
                        if (results && cJSON_GetArraySize(results) > 0) {
                            cJSON *result = cJSON_GetArrayItem(results, 0);
                            cJSON *location = cJSON_GetObjectItem(result, "location");
                            cJSON *now = cJSON_GetObjectItem(result, "now");
                            cJSON *update = cJSON_GetObjectItem(result, "last_update");

                            if (location && now && update) {
                                cJSON *city = cJSON_GetObjectItem(location, "name");
                                cJSON *text = cJSON_GetObjectItem(now, "text");
                                cJSON *temperature = cJSON_GetObjectItem(now, "temperature");
                                if (city && text && temperature) {
                                    printf("City: %s | Weather: %s | Temp: %s | Updated: %s\r\n",city->valuestring, text->valuestring, temperature->valuestring, update->valuestring);
                                }
                            }
                        }
                        cJSON_Delete(root);
                    } else {
                        ESP_LOGE("weather_task", "Failed to parse JSON");
                    }

                } else {
                    ESP_LOGE("weather_task", "Failed to read response");
                }
            }
            esp_http_client_close(client);
        } else {
            ESP_LOGE("weather_task", "HTTP connection failed: %s", esp_err_to_name(err));
        }
        vTaskDelay(pdMS_TO_TICKS(5000));
    }
}

void clear_all_time_show(void)
{
	global_time_show = 0x0000F0030000;
}
void set_hh_seg(uint8_t _value)
{
	switch(_value)
	{
		case 0:global_time_show |= 0x0000F0034000;break;
		case 1:global_time_show |= 0x0000F0030080;break;
		case 2:global_time_show |= 0x0000F0030040;break;
		case 3:global_time_show |= 0x0000F0030020;break;
		case 4:global_time_show |= 0x0000F0030010;break;
		case 5:global_time_show |= 0x0000F0030008;break;
		case 6:global_time_show |= 0x0000F0030004;break;
		case 7:global_time_show |= 0x0000F0030002;break;
		case 8:global_time_show |= 0x0000F0030001;break;
		case 9:global_time_show |= 0x0000F0038000;break;
		default:break;
	}
}
void set_hl_seg(uint8_t _value)
{
	switch(_value)
	{
		case 0:global_time_show |= 0x0000F0130000;break;
		case 1:global_time_show |= 0x0000F0032000;break;
		case 2:global_time_show |= 0x0000F0031000;break;
		case 3:global_time_show |= 0x0000F0030800;break;
		case 4:global_time_show |= 0x0000F0030400;break;
		case 5:global_time_show |= 0x0000F0030200;break;
		case 6:global_time_show |= 0x0000F0030100;break;
		case 7:global_time_show |= 0x0000F0830000;break;
		case 8:global_time_show |= 0x0000F0430000;break;
		case 9:global_time_show |= 0x0000F0230000;break;
		default:break;
	}
}
void set_mh_seg(uint8_t _value)
{
	switch(_value)
	{
		case 0:global_time_show |= 0x0004F0030000;break;
		case 1:global_time_show |= 0x0000F8030000;break;
		case 2:global_time_show |= 0x0000F4030000;break;
		case 3:global_time_show |= 0x0000F2030000;break;
		case 4:global_time_show |= 0x0000F1030000;break;
		case 5:global_time_show |= 0x0080F0030000;break;
		case 6:global_time_show |= 0x0040F0030000;break;
		case 7:global_time_show |= 0x0020F0030000;break;
		case 8:global_time_show |= 0x0010F0030000;break;
		case 9:global_time_show |= 0x0008F0030000;break;
		default:break;
	}
}
void set_ml_seg(uint8_t _value)
{
	switch(_value)
	{
		case 0:global_time_show |= 0x0100F0030000;break;
		case 1:global_time_show |= 0x0002F0030000;break;
		case 2:global_time_show |= 0x0001F0030000;break;
		case 3:global_time_show |= 0x8000F0030000;break;
		case 4:global_time_show |= 0x4000F0030000;break;
		case 5:global_time_show |= 0x2000F0030000;break;
		case 6:global_time_show |= 0x1000F0030000;break;
		case 7:global_time_show |= 0x0800F0030000;break;
		case 8:global_time_show |= 0x0400F0030000;break;
		case 9:global_time_show |= 0x0200F0030000;break;
		default:break;
	}
}

void time_sync_notification_cb(struct timeval *tv)
{
    ESP_LOGI(TAG, "Notification of a time synchronization event");
}
static void obtain_time(void)
{
//    ESP_ERROR_CHECK( nvs_flash_init() );
//    ESP_ERROR_CHECK(esp_netif_init());
//    ESP_ERROR_CHECK( esp_event_loop_create_default() );

    /* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig.
     * Read "Establishing Wi-Fi or Ethernet Connection" section in
     * examples/protocols/README.md for more information about this function.
     */
//    ESP_ERROR_CHECK(example_connect());

    ESP_LOGI(TAG, "Initializing and starting SNTP");
    /*
     * This is the basic default config with one server and starting the service
     */
    esp_sntp_config_t config = ESP_NETIF_SNTP_DEFAULT_CONFIG(CONFIG_SNTP_TIME_SERVER);

    config.sync_cb = time_sync_notification_cb;     // Note: This is only needed if we want

    esp_netif_sntp_init(&config);

    int retry = 0;
    const int retry_count = 15;
    while (esp_netif_sntp_sync_wait(2000 / portTICK_PERIOD_MS) == ESP_ERR_TIMEOUT && ++retry < retry_count) 
    {
        ESP_LOGI(TAG, "Waiting for system time to be set... (%d/%d)", retry, retry_count);
    }

//    ESP_ERROR_CHECK( example_disconnect() );
//    esp_netif_sntp_deinit();
}
static void clock_task(void *pvParameters)
{
    time_t now;
    struct tm timeinfo;
    time(&now);
    localtime_r(&now, &timeinfo);
    
    if (timeinfo.tm_year < (2016 - 1900))	//Is time set? If not, tm_year will be (1970 - 1900).
    {
        ESP_LOGI(TAG, "Time is not set yet. Connecting to WiFi and getting time over NTP.");
        obtain_time();
    }

    SPI_GPIO_Init();//初始化
	SPI_MRES_Clr();
	vTaskDelay(10 / portTICK_PERIOD_MS);
	SPI_MRES_Set();

    while (1) 
    {
	    char strftime_buf[64];
	
	    if(++boot_count >= 300) {obtain_time();boot_count=0;}
        time(&now);	// update 'now' variable with current time
	    setenv("TZ", "CST-8", 1);	// Set timezone to China Standard Time
	    tzset();
	    localtime_r(&now, &timeinfo);
	    strftime(strftime_buf, sizeof(strftime_buf), "%c", &timeinfo);
	    printf("The current date/time in Beijing is: %s \n", strftime_buf);

		clear_all_time_show();
		set_hh_seg(timeinfo.tm_hour/10);
		set_hl_seg(timeinfo.tm_hour%10);
		set_mh_seg(timeinfo.tm_min/10);
		set_ml_seg(timeinfo.tm_min%10);
		SPI_RCK_Clr();
		SPI_WR_DATA(global_time_show);
		SPI_RCK_Set();
       	vTaskDelay(pdMS_TO_TICKS(5000));
    }
}

static void ip_event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
{
    wifi_mode_t mode;

    switch (event_id) 
    {
    	case IP_EVENT_STA_GOT_IP: 
    	{
	        esp_blufi_extra_info_t info;
	
	        xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
	        esp_wifi_get_mode(&mode);
	
	        memset(&info, 0, sizeof(esp_blufi_extra_info_t));
	        memcpy(info.sta_bssid, gl_sta_bssid, 6);
	        info.sta_bssid_set = true;
	        info.sta_ssid = gl_sta_ssid;
	        info.sta_ssid_len = gl_sta_ssid_len;
	        gl_sta_got_ip = true;
	        if (ble_is_connected == true) 
	        {
	            esp_blufi_send_wifi_conn_report(mode, ESP_BLUFI_STA_CONN_SUCCESS, softap_get_current_connection_number(), &info);
	        } else {
	            printf("BLUFI BLE is not connected yet\n");
	        }
	
	        xTaskCreate(weather_task, "weather_task", 4096, NULL, 5, NULL);
	        xTaskCreate(clock_task, "clock_task", 4096, NULL, 5, NULL);
	        break;
	    }
	    default:break;
    }
    return;
}

static void wifi_event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
{
    wifi_event_sta_connected_t *event;
    wifi_event_sta_disconnected_t *disconnected_event;

    switch (event_id) {
    case WIFI_EVENT_STA_START:
        example_wifi_connect();
        break;
    case WIFI_EVENT_STA_CONNECTED:
        gl_sta_connected = true;
        gl_sta_is_connecting = false;
        event = (wifi_event_sta_connected_t*) event_data;
        memcpy(gl_sta_bssid, event->bssid, 6);
        memcpy(gl_sta_ssid, event->ssid, event->ssid_len);
        gl_sta_ssid_len = event->ssid_len;
        break;
    case WIFI_EVENT_STA_DISCONNECTED:
        /* Only handle reconnection during connecting */
        if (gl_sta_connected == false && example_wifi_reconnect() == false) {
            gl_sta_is_connecting = false;
            disconnected_event = (wifi_event_sta_disconnected_t*) event_data;
            example_record_wifi_conn_info(disconnected_event->rssi, disconnected_event->reason);
        }
        /* This is a workaround as ESP32 WiFi libs don't currently
           auto-reassociate. */
        gl_sta_connected = false;
        gl_sta_got_ip = false;
        memset(gl_sta_ssid, 0, 32);
        memset(gl_sta_bssid, 0, 6);
        gl_sta_ssid_len = 0;
        xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
        break;
    case WIFI_EVENT_AP_START:
        break;
    case WIFI_EVENT_SCAN_DONE: {
        uint16_t apCount = 0;
        esp_wifi_scan_get_ap_num(&apCount);
        if (apCount == 0) {
            BLUFI_INFO("Nothing AP found");
            break;
        }
        wifi_ap_record_t *ap_list = (wifi_ap_record_t *)malloc(sizeof(wifi_ap_record_t) * apCount);
        if (!ap_list) {
            BLUFI_ERROR("malloc error, ap_list is NULL");
            esp_wifi_clear_ap_list();
            break;
        }
        ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(&apCount, ap_list));
        esp_blufi_ap_record_t * blufi_ap_list = (esp_blufi_ap_record_t *)malloc(apCount * sizeof(esp_blufi_ap_record_t));
        if (!blufi_ap_list) {
            if (ap_list) {
                free(ap_list);
            }
            BLUFI_ERROR("malloc error, blufi_ap_list is NULL");
            break;
        }
        for (int i = 0; i < apCount; ++i)
        {
            blufi_ap_list[i].rssi = ap_list[i].rssi;
            memcpy(blufi_ap_list[i].ssid, ap_list[i].ssid, sizeof(ap_list[i].ssid));
        }

        if (ble_is_connected == true) {
            esp_blufi_send_wifi_list(apCount, blufi_ap_list);
        } else {
            BLUFI_INFO("BLUFI BLE is not connected yet\n");
        }

        esp_wifi_scan_stop();
        free(ap_list);
        free(blufi_ap_list);
        break;
    }
    case WIFI_EVENT_AP_STACONNECTED: {
        wifi_event_ap_staconnected_t* event = (wifi_event_ap_staconnected_t*) event_data;
        BLUFI_INFO("station "MACSTR" join, AID=%d", MAC2STR(event->mac), event->aid);
        break;
    }
    case WIFI_EVENT_AP_STADISCONNECTED: {
        wifi_event_ap_stadisconnected_t* event = (wifi_event_ap_stadisconnected_t*) event_data;
        BLUFI_INFO("station "MACSTR" leave, AID=%d, reason=%d", MAC2STR(event->mac), event->aid, event->reason);
        break;
    }

    default:
        break;
    }
    return;
}

static void initialise_wifi(void)
{
    wifi_event_group = xEventGroupCreate();
    esp_netif_init();
    esp_event_loop_create_default();
    esp_netif_t *sta_netif = esp_netif_create_default_wifi_sta();
    assert(sta_netif);
    esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL);
    esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &ip_event_handler, NULL);

    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    esp_wifi_init(&cfg);
    esp_wifi_set_mode(WIFI_MODE_STA);
    example_record_wifi_conn_info(EXAMPLE_INVALID_RSSI, EXAMPLE_INVALID_REASON);
    esp_wifi_start();
}

static esp_blufi_callbacks_t example_callbacks = {
    .event_cb = example_event_callback,
    .negotiate_data_handler = blufi_dh_negotiate_data_handler,
    .encrypt_func = blufi_aes_encrypt,
    .decrypt_func = blufi_aes_decrypt,
    .checksum_func = blufi_crc_checksum,
};

static void example_event_callback(esp_blufi_cb_event_t event, esp_blufi_cb_param_t *param)
{
    /* actually, should post to blufi_task handle the procedure,
     * now, as a example, we do it more simply */
    switch (event) {
    case ESP_BLUFI_EVENT_INIT_FINISH:
        printf("BLUFI init finish\n");

        esp_blufi_adv_start();
        break;
    case ESP_BLUFI_EVENT_DEINIT_FINISH:
        BLUFI_INFO("BLUFI deinit finish\n");
        break;
    case ESP_BLUFI_EVENT_BLE_CONNECT:
        printf("BLUFI ble connect\n");
        ble_is_connected = true;
        esp_blufi_adv_stop();
        blufi_security_init();
        break;
    case ESP_BLUFI_EVENT_BLE_DISCONNECT:
        printf("BLUFI ble disconnect\n");
        ble_is_connected = false;
        blufi_security_deinit();
        esp_blufi_adv_start();
        break;
    case ESP_BLUFI_EVENT_SET_WIFI_OPMODE:
        printf("BLUFI Set WIFI opmode %d\n", param->wifi_mode.op_mode);
        ESP_ERROR_CHECK( esp_wifi_set_mode(param->wifi_mode.op_mode) );
        break;
    case ESP_BLUFI_EVENT_REQ_CONNECT_TO_AP:
        printf("BLUFI requset wifi connect to AP\n");
        /* there is no wifi callback when the device has already connected to this wifi
        so disconnect wifi before connection.
        */
        esp_wifi_disconnect();
        example_wifi_connect();
        break;
    case ESP_BLUFI_EVENT_REQ_DISCONNECT_FROM_AP:
        BLUFI_INFO("BLUFI requset wifi disconnect from AP\n");
        esp_wifi_disconnect();
        break;
    case ESP_BLUFI_EVENT_REPORT_ERROR:
        printf("BLUFI report error, error code %d\n", param->report_error.state);
        esp_blufi_send_error_info(param->report_error.state);
        break;
    case ESP_BLUFI_EVENT_GET_WIFI_STATUS: {
        wifi_mode_t mode;
        esp_blufi_extra_info_t info;

        esp_wifi_get_mode(&mode);

        if (gl_sta_connected) {
            memset(&info, 0, sizeof(esp_blufi_extra_info_t));
            memcpy(info.sta_bssid, gl_sta_bssid, 6);
            info.sta_bssid_set = true;
            info.sta_ssid = gl_sta_ssid;
            info.sta_ssid_len = gl_sta_ssid_len;
            esp_blufi_send_wifi_conn_report(mode, gl_sta_got_ip ? ESP_BLUFI_STA_CONN_SUCCESS : ESP_BLUFI_STA_NO_IP, softap_get_current_connection_number(), &info);
        } else if (gl_sta_is_connecting) {
            esp_blufi_send_wifi_conn_report(mode, ESP_BLUFI_STA_CONNECTING, softap_get_current_connection_number(), &gl_sta_conn_info);
        } else {
            esp_blufi_send_wifi_conn_report(mode, ESP_BLUFI_STA_CONN_FAIL, softap_get_current_connection_number(), &gl_sta_conn_info);
        }
        BLUFI_INFO("BLUFI get wifi status from AP\n");

        break;
    }
    case ESP_BLUFI_EVENT_RECV_SLAVE_DISCONNECT_BLE:
        printf("blufi close a gatt connection");
        esp_blufi_disconnect();
        break;
    case ESP_BLUFI_EVENT_DEAUTHENTICATE_STA:
        /* TODO */
        break;
    case ESP_BLUFI_EVENT_RECV_STA_BSSID:
        memcpy(sta_config.sta.bssid, param->sta_bssid.bssid, 6);
        sta_config.sta.bssid_set = 1;
        esp_wifi_set_config(WIFI_IF_STA, &sta_config);
        BLUFI_INFO("Recv STA BSSID %s\n", sta_config.sta.ssid);
        break;
    case ESP_BLUFI_EVENT_RECV_STA_SSID:
        strncpy((char *)sta_config.sta.ssid, (char *)param->sta_ssid.ssid, param->sta_ssid.ssid_len);
        sta_config.sta.ssid[param->sta_ssid.ssid_len] = '\0';
        esp_wifi_set_config(WIFI_IF_STA, &sta_config);
        printf("Recv STA SSID %s\n", sta_config.sta.ssid);
        break;
	case ESP_BLUFI_EVENT_RECV_STA_PASSWD:
        strncpy((char *)sta_config.sta.password, (char *)param->sta_passwd.passwd, param->sta_passwd.passwd_len);
        sta_config.sta.password[param->sta_passwd.passwd_len] = '\0';
        esp_wifi_set_config(WIFI_IF_STA, &sta_config);
        printf("Recv STA PASSWORD %s\n", sta_config.sta.password);
        break;
    case ESP_BLUFI_EVENT_GET_WIFI_LIST: {
        wifi_scan_config_t scanConf = {
            .ssid = NULL,
            .bssid = NULL,
            .channel = 0,
            .show_hidden = false
        };
        esp_err_t ret = esp_wifi_scan_start(&scanConf, true);
        if (ret != ESP_OK) {
            esp_blufi_send_error_info(ESP_BLUFI_WIFI_SCAN_FAIL);
        }
        break;
    }
    case ESP_BLUFI_EVENT_RECV_CUSTOM_DATA:
        BLUFI_INFO("Recv Custom Data %" PRIu32 "\n", param->custom_data.data_len);
        esp_log_buffer_hex("Custom Data", param->custom_data.data, param->custom_data.data_len);
        break;
    case ESP_BLUFI_EVENT_RECV_USERNAME:
        /* Not handle currently */
        break;
    case ESP_BLUFI_EVENT_RECV_CA_CERT:
        /* Not handle currently */
        break;
    case ESP_BLUFI_EVENT_RECV_CLIENT_CERT:
        /* Not handle currently */
        break;
    case ESP_BLUFI_EVENT_RECV_SERVER_CERT:
        /* Not handle currently */
        break;
    case ESP_BLUFI_EVENT_RECV_CLIENT_PRIV_KEY:
        /* Not handle currently */
        break;
    case ESP_BLUFI_EVENT_RECV_SERVER_PRIV_KEY:
        /* Not handle currently */
        break;
    default:
        break;
    }
}

void test_show(void)
{
	volatile uint8_t cnt = 0;

	SPI_RCK_Clr();
	switch(cnt++)
	{
		case 0:SPI_WR_DATA(0x0104F0134000);break;
		case 1:SPI_WR_DATA(0x0002F8032080);break;
		case 2:SPI_WR_DATA(0x0001F4031040);break;
		case 3:SPI_WR_DATA(0x8000F2030820);break;
		case 4:SPI_WR_DATA(0x4000F1030410);break;
		case 5:SPI_WR_DATA(0x2080F0030208);break;
		case 6:SPI_WR_DATA(0x1040F0030104);break;
		case 7:SPI_WR_DATA(0x0820F0830002);break;
		case 8:SPI_WR_DATA(0x0410F0430001);break;
		case 9:SPI_WR_DATA(0x0208F0238000);break;
		default:cnt=0;break;
	}
	SPI_RCK_Set();
}



void app_main(void)
{
    esp_err_t ret;

    // Initialize NVS
    ret = nvs_flash_init();
    if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
        ESP_ERROR_CHECK(nvs_flash_erase());
        ret = nvs_flash_init();
    }
    ESP_ERROR_CHECK( ret );

    initialise_wifi();

#if CONFIG_BT_CONTROLLER_ENABLED || !CONFIG_BT_NIMBLE_ENABLED
    ret = esp_blufi_controller_init();
    if (ret) {
        BLUFI_ERROR("%s BLUFI controller init failed: %s\n", __func__, esp_err_to_name(ret));
        return;
    }
#endif

    ret = esp_blufi_host_and_cb_init(&example_callbacks);
    if (ret) {
        BLUFI_ERROR("%s initialise failed: %s\n", __func__, esp_err_to_name(ret));
        return;
    }

    printf("BLUFI VERSION %04x\n", esp_blufi_get_version());


    while (1)
	{

    	vTaskDelay(1000 / portTICK_PERIOD_MS);
	}

}

